<?php

namespace app\admin\controller;

use app\common\controller\Backend;
use think\Db;
use think\Cache;
/**
 * 1.06 收币地址
 *
 * @icon fa fa-circle-o
 */
class Guiji extends Backend
{
    
    /**
     * Guiji模型对象
     * @var \app\admin\model\Guiji
     */
    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\Guiji;

    }

    /**
     * 查看
     */
    public function index()
    {
        //设置过滤方法
        $this->request->filter(['strip_tags']);
        if ($this->request->isAjax()) {
            //如果发送的来源是Selectpage，则转发到Selectpage
            if ($this->request->request('keyField')) {
                return $this->selectpage();
            }
            list($where, $sort, $order, $offset, $limit) = $this->buildparams();
            $total = $this->model
                ->where($where)
                ->order($sort, $order)
                ->count();
            $list = $this->model
                ->where($where)
                ->order($sort, $order)
                ->limit($offset, $limit)
                ->select();
           
            $result = array("total" => $total, "rows" => $list);
            return json($result);
        }
        $this->assignconfig("guiji_min",config('site.guiji_min'));
        $this->assignconfig("guiji_kgf",config('site.guiji_kgf'));
        $eth_kgf =  db('rtp')->where('type','kgf')->value('price');
        
        $this->assign('guiji_kgf',config('site.guiji_kgf'));
        $this->assign('eth_kgf',$eth_kgf);
        return $this->view->fetch();
    }
    
    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将application/admin/library/traits/Backend.php中对应的方法复制到当前控制器,然后进行修改
     */
    
    //执行归集
    public function guiji_do(){


        // $eth_kgf =  db('rtp')->where('type','kgf')->value('price');
        // if(config('site.guiji_kgf') < $eth_kgf){
        //     $this->error('当前矿工费设置价格小于ETH标准价格，请去系统设置修改参数，否则容易出现转账失败或转账时间过长等因素');
        // }
        // $this->error('请稍后');
        // return json(request()->param());
        // 取参数
        set_time_limit(0);
        //先查一遍历史归集到账记录
        $this->piliang_cha_guiji_daozhang();

        $id = request()->param()['ids'];
        $bizhong = request()->param()['bizhong'];
        $bizhong = strtolower($bizhong);
        Db::startTrans();   // 启动事务-------------
        $qianbao_sysetm = db('qianbao_sysetm_addr')->where('id',$id)->lock(true)->find();   //加了行锁
        if(!$qianbao_sysetm){
            Db::rollback();     // 回滚事务-------------
            $this->error('没找到数据');
        }
        $erc20_last_num = $qianbao_sysetm[$bizhong.'_last_num']*1;
        if($erc20_last_num<config('site.guiji_min')[strtoupper($bizhong)]){
            Db::rollback();     // 回滚事务-------------
            $this->error('不足最小归集数量');
        }
        if(db('qianbao_sysetm_log')->where('uid',$qianbao_sysetm['uid'])->where('type','20')->where('zt',3)->find()){
            Db::rollback();     // 回滚事务-------------
            $this->error('该账号上笔归集还未到账');
        }
        $userinfo = db('user')->where('id',$qianbao_sysetm['uid'])->find();
        $uname = $userinfo['username'];
        $address = $qianbao_sysetm['addr'];

        //查余额
        $erc20_num = erc_yue($address,$bizhong);
        $eth_num = erc_yue($address,'eth');
        if(!$erc20_num['zt'] || !$eth_num['zt']){
            $this->error($eth_num['msg']);
        }

        
        $erc20_num = $erc20_num['data']*1;
        $eth_num = $eth_num['data']*1;

        // echo 'erc20_num='.$erc20_num.'》eth_num='.$eth_num.'》erc20_last_num='.$erc20_last_num.' ||| ';   //km

        // 自动归集
        // ===更新ETH余额记录
        if($qianbao_sysetm['eth_last_num']<>$eth_num){  //？小心有精度BUG
            $ret_eth = db('qianbao_sysetm_addr')->where('uid',$userinfo['id'])->update([
                'eth_last_num'=>$eth_num,
                'eth_last_time'=>time(),
            ]);
            if(!$ret_eth){
                Db::rollback();     // 回滚事务-------------
                $this->error('ETH余额更新失败');
            }
        }
        
        //===拨发矿工费》执行归集
        if($eth_num<config('site.guiji_kgf')){  //拨发矿工费
            //===查询是否有进行中的链上交易，并到账处理
            $jiaoyi = db('qianbao_sysetm_log')->where('uname',$uname)->where('type','21')->where('zt',3)->find();
            $erc_daozhang = ''; //初始化
            if($jiaoyi){
                $erc_daozhang = erc_daozhang($jiaoyi['hash']);
                if($erc_daozhang['zt'] <> 0){
                    if($erc_daozhang['zt'] == 1){   //交易成功
                        db('qianbao_sysetm_log')->where('uname',$uname)->where('type','21')->where('zt',3)->update(['zt'=>1]);
                    }elseif($erc_daozhang['zt'] == 2){  //交易失败
                        db('qianbao_sysetm_log')->where('uname',$uname)->where('type','21')->where('zt',3)->update(['zt'=>2]);
                    }
                }else{
                    return json(['zt'=>0,'msg'=>'矿工费到账查询失败','data'=>$erc_daozhang]);
                }
            }

            //===没有交易未完成的 则拨发矿工费
            if(!$jiaoyi || ($jiaoyi && $erc_daozhang['zt'] <> '3')){
                $ret = erc_zhuanzhang('eth',config('accounts')['privatekey'], round(config('site.guiji_kgf') / 2.8,6),$address);
                if($ret['zt']){
                    $hash = $ret['data'];
                    $ret_eth_log = db('qianbao_sysetm_log')->insertGetId([
                        'uid'=>$userinfo['id'],
                        'uname'=>$userinfo['username'],
                        'bizhong'=>'eth',
                        'addr'=>$address,
                        'charge'=>config('site.guiji_kgf'),
                        'money_lian'=>config('site.guiji_kgf')+$eth_num,
                        'note'=>'发放矿工费',
                        'createtime'=>time(),
                        'type'=>'21',
                        'toaddr'=>config('accounts')['addr'],
                        'zt'=>3,
                        'hash'=>$hash
                    ]);
                    if(!$ret_eth_log){
                        Db::rollback();     // 回滚事务-------------
                        $this->error('矿工费发放成功、但数据插入失败');//？应再插入err日志以追踪
                    }else{
                        Db::commit();       // 提交事务-------------
                        return json(['zt'=>1,'msg'=>'矿工费已发放，稍后到账安排归集！']);
                    }
                }else{
                    Db::rollback();     // 回滚事务-------------
                    return json(['zt'=>0,'msg'=>$ret['msg'],'data'=>$ret]);
                }
            }else{
                Db::rollback();     // 回滚事务-------------
                return json(['zt'=>1,'msg'=>'矿工费发放中，稍后再试。。。']);
            }
        }else{  //执行归集
            $ret = erc_zhuanzhang($bizhong,$qianbao_sysetm['privatekey'],$erc20_last_num,config('addr_guiji'));
            if($ret['zt']){
                $hash = $ret['data'];
                $ret_erc_log = db('qianbao_sysetm_log')->insertGetId([
                    'uid'=>$userinfo['id'],
                    'uname'=>$userinfo['username'],
                    'bizhong'=>$bizhong,
                    'addr'=>$address,
                    'money'=>'-'.$erc20_last_num,
                    'money_lian'=>0,
                    'note'=>'系统归集',
                    'createtime'=>time(),
                    'type'=>'20',
                    'toaddr'=>config('addr_guiji'),
                    'zt'=>3,
                    'hash'=>$hash
                ]);
                if(!$ret_erc_log){
                    Db::rollback();     // 回滚事务-------------
                    $this->error('归集成功、但数据插入失败');//？应再插入err日志以追踪
                }else{
                    Db::commit();       // 提交事务-------------
                    return json(['zt'=>1,'msg'=>$erc20_last_num.' 枚'.$bizhong.'归集成功，稍后查看到账状态！']);
                }
            }else{
                Db::rollback();     // 回滚事务-------------
                return json(['zt'=>0,'msg'=>'归集链上发布交易失败','data'=>$ret]);
            }
        }
    }

    public function piliang_cha_guiji_daozhang(){
        // set_time_limit(0);
        $lists=db('qianbao_sysetm_log')->where('type',20)->where('zt',3)->select();
        foreach ($lists as $list) {
            Db::startTrans();
            try {
                $ret = erc_daozhang($list['hash']);
                if($ret['zt']==1){
                    $ret_log = db('qianbao_sysetm_log')->where('id',$list['id'])->update(['zt'=>1,'memo'=>$ret['msg']]);
                    $ret_last_num = db('qianbao_sysetm_addr')->where('uid',$list['uid'])
                        ->inc($list['bizhong'].'_last_num',$list['add'])->update([$list['bizhong'].'_last_time'=>time()]);
                }elseif($ret['zt']==2){
                    $ret_log = db('qianbao_sysetm_log')->where('id',$list['id'])->update(['zt'=>2,'memo'=>$ret['msg']]);
                }else{
                    $ret_log = db('qianbao_sysetm_log')->where('id',$list['id'])->update(['memo'=>$ret['msg']]);
                    // echo $list['id'].'>>>'.$ret['msg'].'<hr>';
                }
                Db::commit();  
            } catch (\Exception $e) {
                Db::rollback();
            }
        }
    }


}
